﻿using System;
using Microsoft.Build.Framework;
using Codeplex.STSDTS.MSBuildTasks.DeploymentServices;
using System.Net;
using Codeplex.STSDTS.Entities;
using System.Collections.Generic;
using System.IO;

namespace Codeplex.STSDTS.MSBuildTasks
{

    /// <summary>
    /// Class representing a build task for use with Team Foundation Build.
    /// This task invokes the STSDTS deployment web service and downloads the solutions as described in the farm XML file.
    /// </summary>
    public class DownloadFarm : BaseTask
    {

        #region Properties

        /// <summary>
        /// Url of the deployment web service
        /// </summary>
        [Required]
        public string DeploymentServiceUrl
        {
            get;
            set;
        }

        /// <summary>
        /// Location of the farm XML file
        /// </summary>
        [Required]
        public string FarmFile
        {
            get;
            set;
        }

        /// <summary>
        /// Location where WSPs are stored on disk
        /// </summary>
        [Required]
        public string BinariesLocation
        {
            get;
            set;
        }

        /// <summary>
        /// Username for calling the deployment web service
        /// </summary>
        [Required]
        public string UserName
        {
            get;
            set;
        }

        /// <summary>
        /// Password for calling the deployment web service
        /// </summary>
        [Required]
        public string Password
        {
            get;
            set;
        }

        /// <summary>
        /// Domain for calling the deployment web service
        /// </summary>
        public string Domain
        {
            get;
            set;
        }

        private DeploymentService _deploymentService;

        #endregion Properties


        /// <summary>
        /// Downloads given solutions
        /// </summary>
        /// <param name="solutions">Solutions to download</param>
        private void DownloadSolutions(IEnumerable<Solution> solutions)
        {
            //Loop solutions
            foreach (var solution in solutions)
            {
                var taskId = CreateBuildStep("Downloading {0}", solution.FileName);
                try
                {
                    //Create file on disk and download solution to it
                    var file = new FileInfo(string.Format(@"{0}\{1}", BinariesLocation, solution.FileName));
                    using (var stream = file.Create())
                    {
                        var buffer = _deploymentService.DownloadSolution(solution.Id);
                        Log("Downloaded solution file size: {0}", buffer.Length);
                        stream.Write(buffer, 0, buffer.Length);
                    }
                    //Log success
                    EndBuildStep(taskId, true);
                    Log("Downloaded {0}", solution.FileName);
                }
                catch(Exception ex)
                {
                    //Log error
                    EndBuildStep(taskId, false);
                    Log("Error while downloading {0}: {1}", solution.FileName, ex.Message);
                }
                
            }
        }

       

        override public bool Execute()
        {
            //Load farm file
            var farm = Farm.Deserialize(FarmFile);

            //Setup deployment service with given credentials
            _deploymentService = new DeploymentService
                                        {
                                            Credentials =
                                                new NetworkCredential
                                                {
                                                    UserName = UserName,
                                                    Password = Password
                                                },
                                            Url = DeploymentServiceUrl
                                        };
            //Also set domain if it is not null or empty
            if (!string.IsNullOrEmpty(Domain))
                ((NetworkCredential)_deploymentService.Credentials).Domain = Domain;

            //Download solutions
            DownloadSolutions(farm.Solutions);

            return true;
        }

    }
}
